import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Story } from './entities/story';
import { Repository } from 'typeorm';
import { ReptileHtml } from '../common/reptileHtml';
import { Image } from './entities/image';

@Injectable()
export class StoryService {
  constructor(
    @InjectRepository(Story)
    private readonly storyRepository: Repository<Story>,
  ) {}

  async queryNewsLatest() {
    const query = await this.storyRepository
      .createQueryBuilder('s')
      .select([`DATE_FORMAT(s.createdAt, '%Y-%m-%d') as date`])
      .groupBy(`DATE_FORMAT(s.createdAt, '%Y-%m-%d')`)
      .orderBy('date', 'DESC')
      .limit(1)
      .getRawMany();
    const dates = await this.storyRepository
      .createQueryBuilder('s')
      .select([
        's.id as id',
        's.title as title',
        's.url as url',
        's.hint as hint',
        'i.image as image',
        'i.storyId as storyId',
        's.type as type',
        `DATE_FORMAT(s.createdAt, '%Y-%m-%d') as date`,
      ])
      .leftJoin('images', 'i', 'i.storyId = s.id')
      .orderBy('s.createdAt', 'DESC')
      .where(`DATE_FORMAT(s.createdAt, '%Y-%m-%d') in (:...date)`, {
        date: query.map((item) => item.date),
      })
      .getRawMany();
    const list = await this.updateStoryInfo(dates);
    return query.map((item) => {
      return {
        date: item.date,
        stories: list.filter((story) => story['date'] === item.date),
      };
    });
  }

  async insertNews(sourceUrl: string) {
    const query = await this.storyRepository
      .createQueryBuilder('s')
      .select('s.url as url')
      .getRawMany();

    const tableUrl = query.map((item) => item.url);
    console.log(tableUrl);
    const list = await ReptileHtml.getStoryList(sourceUrl);

    const inserts = list.filter((item) => !tableUrl.includes(item));

    return await this.storyRepository.manager.insert(
      Story,
      inserts.map((item) => {
        return {
          url: item,
          body: '',
        };
      }),
    );
  }

  async queryNewsBefore(time: string) {
    let count = 1;
    const date = await this.queryNewsDay(time);
    console.log(date);
    const query = this.storyRepository
      .createQueryBuilder('s')
      .select([
        's.id as id',
        's.title as title',
        's.hint as hint',
        'i.image as image',
        'i.storyId as storyId',
        's.type as type',
        `s.url as url`,
        `DATE_FORMAT(s.createdAt, '%Y-%m-%d') as date`,
      ])
      .leftJoin('images', 'i', 'i.storyId = s.id')
      .orderBy('s.createdAt', 'DESC')
      .where(
        `DATE_FORMAT(s.createdAt, '%Y-%m-%d') = DATE_SUB( :date, INTERVAL ${count} DAY)`,
        {
          date: time,
        },
      );
    let list = await query.getRawMany();

    while (!list.length && count < 10) {
      count++;
      list = await query
        .where(
          `DATE_FORMAT(s.createdAt, '%Y-%m-%d') = DATE_SUB( :date, INTERVAL ${count} DAY)`,
          {
            date: time,
          },
        )
        .getRawMany();
    }
    return await this.updateStoryInfo(list);
  }

  async queryNewsDay(time: string) {
    const date = await this.storyRepository
      .createQueryBuilder('s')
      .select([`DATE_FORMAT(s.createdAt, '%Y-%m-%d') as date`])
      .where(`DATE_FORMAT(s.createdAt, '%Y-%m-%d') <= :date`, {
        date: time,
      })
      .groupBy(`DATE_FORMAT(s.createdAt, '%Y-%m-%d')`)
      .orderBy('date', 'DESC')
      .limit(100)
      .getRawMany();
    return date.map((item) => item.date);
  }

  async queryNewsDetail(id: string) {
    const query = this.storyRepository
      .createQueryBuilder('s')
      .select([
        's.id as id',
        's.title as title',
        's.hint as hint',
        's.type as type',
        's.body as body',
        's.url as url',
        's.css as css',
        'i.image as image',
        's.image_hue as image_hue',
      ])
      .leftJoin('images', 'i', 'i.storyId = s.id')
      .where('s.id = :id', { id });
    const story = await query.getRawOne();
    if (story.id && !story.css) {
      const { css } = await ReptileHtml.getHtml(story.url);
      story.css = css.toString();
      await this.storyRepository.update(id, { css: css.toString() || 'null' });
    }

    return story;
  }

  async queryStoryExtra(id: string) {
    return Promise.resolve(undefined);
  }

  async updateStoryInfo(list) {
    const storyMap = new Map();
    let count = 0;
    while (list.length > count) {
      const { id, date, title, hint, type, url } = list[count];
      const images = list
        .filter((story) => story['storyId'] === id)
        .map((v) => v.image);
      console.log(images);
      storyMap.set(id, {
        id,
        date,
        title,
        hint,
        type,
        image: images[0],
        images,
      });
      if (images.length === 0) {
        const res = await ReptileHtml.getHtml(url);
        await this.storyRepository.update(id, {
          title: res.title,
          body: res.body,
          hint: res.hint,
          url: url,
          image_hue: res.imageHue,
          ga_prefix: res.gaPrefix,
          type: res.type,
        });
        console.log('插入数据', id);
        await this.storyRepository.manager.insert(Image, [
          ...res.images.map((i) => ({ storyId: id, image: i })),
        ]);
      }
      count++;
    }

    return Array.from(storyMap.values());
  }
}
